
// score
// 
var PIKACHU = {
	_url : 'http://www.youbrainy.com/pikachu/pikachu_games/ws',
	_scoreUrl : 'http://www.youbrainy.com/pikachu/pikachu_games/score',
	gWidth : 16,
	gHeight : 9,
	gCellsNo : 0,
	gMaxValue : 36,
	cSizeW : 40,
	cSizeH : 50,
	_jP : null, // jQuery object of game panel
	_jPCells : null, // jQuery objects of game cells
	_jCache : {},
	_mode : 'standard', // standard, findhelper
	_stage : 1,
	_stageLengthStandard : 630, // seconds
	_maxStage : 7,
	_refresh : 10,
	_state : '', // no, playing, paused
	_recentMoves : [],// {i1 : 0, j1 : 0, i2 : 0, j2 : 0}
	_lastMove : {i1 : -1, j1 : -1, i2 : -1, j2 : -1},
	_token : '',
	_timer : 0,
	_timerInst : null,
	_score : 0,
	_findDirections : [{i : 1, j : 0}, {i : 0, j : 1}, {i : 0, j : -1}, {i : -1 , j : 0}],
	init : function(){
		this._genGame();
	},
	start : function(){
		this._newGame();
		$('#p_newgame').text('Bắt đầu lại');
	},
	restart : function(){
		this._newGame();
	},
	_genGame : function(){
		var html0 = '<div class="p_toolbar">'
				+ '<a href="#" class="p_button p_button_newgame" onclick="PIKACHU.start();return false;">'
				+ '		<i><i><span id="p_newgame">Bắt đầu</span></i></i>'
				+ '</a>'
				+ '<a href="#" class="p_button p_button_stage" onclick="return false;">'
				+ '		<i><i>Bài <span id="p_stage">1</span>/<span id="p_maxstage">7</span>, mạng <span id="p_refresh">10</span></i></i>'
				+ '</a>'
				+ '<a href="#" class="p_button p_button_refresh" onclick="PIKACHU.refresh();return false;">'
				+ '		<i><i>Chủ động đảo vị trí </i></i>'
				+ '</a>'
				+ '<a href="#" class="p_button p_button_pause" onclick="PIKACHU.pause();return false;">'
				+ '		<i><i><span id="p_pause">Tạm dừng</span></i></i>'
				+ '</a>'
				+ '<a href="#" class="p_button p_time" onclick="return false;">'
				+ '		<i><i><span id="p_timer">0</span></i></i>'
				+ '</a>'
				+ '<a href="#" class="p_button p_score" onclick="return false;">'
				+ '		<i><i><span id="p_score">0</span></i></i>'
				+ '</a>'
			+ '</div>';
		var html1 = '';
		var html2 = '';
		var cSizeW = this.cSizeW;
		var cSizeH = this.cSizeH;
		for(var i = -1; i <= this.gWidth; i++){
			for(var j =- 1; j<= this.gHeight; j++){
				if( i > -1 && j > -1 && i < this.gWidth && j < this.gHeight){
					html1 += '<a class="p" id="p_' + i + '_' + j + '" '
						+ 'style="top:' + (cSizeH * (j + 1) + 30) + 'px;'
						+ 'left:' + (cSizeW * (i + 1)) + 'px"><span class="border"></span></a>';
				}
				html2 += '<div class="c" id="c_' + i + '_' + j + '" '
					+ 'style="top:' + (cSizeH * (j + 1) + 30) + 'px;'
					+ 'left:' + (cSizeW * (i + 1)) + 'px"></div>';
			}
		}
		this._jP = $('#game-panel');
		this._jP.html(html0 + html1 + html2); // .h is the cover panel used with pausing
		this._jPCells = this._jP.find('.p');
		this._jPCells.mouseover(function(){
				PIKACHU.mouseover($(this).data('i') , $(this).data('j'), $(this));
			}).mouseout(function(){
				PIKACHU.mouseout($(this).data('i') , $(this).data('j'), $(this));
			}).click(function(){
				PIKACHU.click($(this).data('i') , $(this).data('j'), $(this));
			}).each(function(index){
				var i = Math.floor(index / PIKACHU.gHeight);
				var j = index - i * PIKACHU.gHeight;
				$(this).data('i', i)
						.data('j', j).hide();
			});
	},
	_newGame : function(){
		this.gCellsNo = this.gWidth * this.gHeight;
		this._stage = 0;
		this._refresh = 10;
		this._score = 0;
		this._state = 'playing';
		this._request('startgame');
		$('#game-panel').css('height', '570px');
		this._newStage();
	},
	_newStage : function(){
		if(this._stage == this._maxStage){
			return;
		};
		this.gCellsNo = this.gWidth * this.gHeight;
		this._stage++;
		this._timer = this._stageLengthStandard;
		this._stopTimer();
		this._startTimer();
		this._randGame();
		this._updateGameStatus();
	},
	_randGame : function(){
		var values = [], i, j, randPos, val, tg;
		for(i= 0; i< this.gWidth; i++){
			for(j=0; j< this.gHeight; j++){
				val = (i * this.gHeight + j + 1) % this.gMaxValue;
				values.push(val == 0 ? this.gMaxValue : val);
			}
		}
		for(i=0; i<values.length; i++){
			randPos = Math.round(Math.random() * values.length);
			if(randPos > values.length - 1){
				randPos = values.length - 1;
			}
			tg = values[i];
			values[i] = values[randPos];
			values[randPos] = tg;
		}
		this._jPCells.each(function(index){
			var i = $(this).data('i');
			var j = $(this).data('j');
			var val = values[index];
			var curVal = $(this).data('value');
			if(curVal){
				$(this).removeClass('p_' + curVal);
			}
			$(this).data('value', val)
					.data('connected', 0)
					.addClass('p_' + val);
			if (i == 0 || i == PIKACHU.gWidth-1 || j == 0 || j == PIKACHU.gHeight-1) {
				$(this).data('blocked', 0);
			} else {
				$(this).data('blocked', 1);
			}
		});
		this._jPCells.each(function(){
			var k, d, i, j, ni, nj, val, t;
			i = $(this).data('i');
			j = $(this).data('j');
			val = $(this).data('value');
			if($(this).data('blocked')){
				for(k=0; k< PIKACHU._findDirections.length; k++){
					d = PIKACHU._findDirections[k];
					ni = i + d.i;
					nj = j + d.j;
					t = PIKACHU._getJObj(ni, nj);
					if(t.data('value') == val){
						$(this).data('blocked', 0);
						t.data('blocked', 0);
					}
				}
			}
		});
		if(!this._checkMovable()){
			this._refresh++;
			this.refresh();
		}
		this._jPCells.show();
	},
	pause : function(){
		if(this._state == 'playing'){
			this._stopTimer();
			this._state = 'paused';
			$('#p_pause').text('Tiếp tục');
			this._jPCells.hide();
			this._request('pause');
		} else if(this._state == 'paused'){
			this._state = 'playing';
			this._startTimer();
			$('#p_pause').text('Tạm dừng');
			this._jPCells.each(function(){
				if($(this).data('connected') == '0'){
					$(this).show();
				}
			});
			this._request('resume');
		}
	},
	_stopTimer : function(){
		if(this._timerInst){
			clearInterval(this._timerInst);
		}
	},
	_startTimer : function(){
		this._timerInst = setInterval(function(){
			PIKACHU._updateTimer();
		}, 1000);
	},
	refresh : function(){
		// can't refresh anymore
		if(this._refresh == 0){
			return;
		}
		var ps = this._getNotConnectedJCells();
		if(!ps.length){
			return;
		}
		for(var i=0; i< ps.length; i++){
			var psi = ps[i];
			var psj = null;
			var change = Math.round(Math.random());
			if(change){
				var j = Math.round(Math.random() * ps.length);
				if(j >= ps.length){
					j = ps.length - 1;
				}
				psj = ps[j];
				var psiValue = psi.data('value');
				var psjValue = psj.data('value');
				if(psiValue == psjValue){
						continue;
				}
				psi.removeClass('p_' + psiValue)
						.data('value', psjValue);
				psj.removeClass('p_' + psjValue)
						.data('value', psiValue);
			}
		}
		// update blockeds
		var d, ni, nj, t, o, val, blocked;
		for(var i=0; i< ps.length; i++){
			o = ps[i];
			val = o.data('value');
			blocked = true;
			for(k=0; k< this._findDirections.length; k++){
				d = this._findDirections[k];
				ni = i + d.i;
				nj = j + d.j;
				if(ni >= 0 && nj >= 0 && ni < this.gWidth && nj < this.gHeight){
					t = PIKACHU._getJObj(ni, nj);
					if(t.data('connected') == 1){
						blocked = false;
					} else if(t.data('value') == val){
						blocked = false;
					} 
				} else {
					blocked = false;
				}
			}
			o.data('blocked', blocked ? 1 : 0);
		}
		// refresh again if can't move anymore
		if(!this._checkMovable()){
			this.refresh();
		} else {
			// accept change
			for(var i=0; i< ps.length; i++){
				var psVal = ps[i].data('value');
				ps[i].addClass('p_' + psVal);
			}
			this._refresh--;
			this._request('refresh');
			this._updateGameStatus();
		}
	},
	click : function(i,j,jObj){
		jObj.addClass('clicked');
		var jClickeds = this._jP.find('.clicked');
		var nClickeds = jClickeds.get().length;
		if( nClickeds == 2){
			var i2 = jObj.data('i');
			var j2 = jObj.data('j');
			var i1 = jClickeds.first().data('i');
			var j1 = jClickeds.first().data('j');
			if(i1 == i2 && j1 == j2){
				var i1 = jClickeds.last().data('i');
				var j1 = jClickeds.last().data('j');
			}
			var points = this._findConnection(i1, j1, i2, j2);
			jClickeds.removeClass('clicked');
			if(points.length){
				jClickeds.data('connected', '1').hide();
				this._lastMove = {
					i1 : i1, j1 : j1, i2 : i2, j2 : j2, value : jObj.data('value'),timestamp : new Date().getTime()
				};
				this._recentMoves.push(this._lastMove);
				this._showingConnection(points);
				this._stageAfterMove();
				this._processAfterMove();
			} else {
				// found no path, set this clicked
				jObj.trigger('click');
			}
		} else if(nClickeds > 2) {
			jClickeds.removeClass('clicked');
		}
	},
	mouseover : function(i,j,jObj){
		// find same
		// get value
		var value = jObj.data('value');
		if(this._mode == 'findhelper'){
			this._jPCells.each(function(index){
				if($(this).data('value') == value && !$(this).hasClass('clicked')){
					$(this).addClass('hover');
				} else {
					$(this).removeClass('hover');
				}
			});
		} else {
			jObj.addClass('hover');
		}
	},
	mouseout : function(i,j,jObj){
		//
		if(this._mode == 'findhelper'){
			this._jPCells.removeClass('hover');
		} else {
			jObj.removeClass('hover');
		}
	},
	_getJObj : function(i,j){
		var id = 'p_' + i + '_' + j;
		if(this._jCache[id] == undefined){
			this._jCache[id] = $('#' + id);
		}
		return this._jCache[id];
	},
	_getCObj : function(i,j){
		var id = 'c_' + i + '_' + j;
		if(this._jCache[id] == undefined){
			this._jCache[id] = $('#' + id);
		}
		return this._jCache[id];
	},
	_findConnection : function(i1, j1, i2, j2){
		var connection = [];
		var jO1 = this._getJObj(i1, j1);
		var jO2 = this._getJObj(i2, j2);
		if(jO1.data('connected') == '1' || jO2.data('connected') == '1'){
				return false;// false
		}
		if(parseInt(jO1.data('value')) != parseInt(jO2.data('value'))){
				return false;// false
		}
		return this._findingConnection(i1, j1, i2, j2, 4, 4, 0);
	},
	_orderDirections : function(i1, j1, i2, j2){
		var dirs = [], nextDirI, nextDirJ, newI, newJ, i, rets;
		for(i =0;i< this._findDirections.length; i++){
			nextDirI = this._findDirections[i].i;
			nextDirJ = this._findDirections[i].j;
			newI = i1 + nextDirI;
			newJ = j1 + nextDirJ;
			dirs.push({index : i, value : Math.abs(newI - i2) + Math.abs(newJ - j2)});
		}
		dirs.sort(function(a,b){return parseInt(a.value) > parseInt(b.value);});
		rets = [];
		for(i=0;i<dirs.length; i++){
			rets.push(this._findDirections[dirs[i].index]);
		}
		return rets;
	},
	_findingConnection : function(i1, j1, i2, j2, dirI, dirJ, change){
		// reset covered area
		if(change == 0){
			change++;
		}
		// recursive end condition
		var conn = [{i : i1, j : j1}];

		if(i1 == i2 && j1 == j2){
			return conn;
		}
		// calculate best direction
		// find connections
		var dirs = this._orderDirections(i1, j1, i2, j2);
		var nextDirI, nextDirJ, xchange, j, newI, newJ, canPass, jObj, rConn;
		for(j = 0; j < dirs.length; j++){
			nextDirI = dirs[j].i;
			nextDirJ = dirs[j].j;
			xchange = change;
			if(dirI !=  nextDirI || dirJ != nextDirJ){
				if(change == 4){
					continue;
				}
				xchange++;
			}
			newI = i1 + nextDirI;
			newJ = j1 + nextDirJ;
			// bound
			if(newI < -1 || newJ < -1 || newI > this.gWidth || newJ > this.gHeight){
				continue;
			}

			canPass = false;
			if(newI == -1 || newJ == -1 || newI == this.gWidth || newJ == this.gHeight){
				canPass = true;
			} else {
				// in bound
				jObj = this._getJObj(newI, newJ);
				if(jObj.data('connected') == '1'){
					canPass = true;
				} else if(newI == i2 && newJ == j2){
					canPass = true;
				}
			}
			if(canPass){
				//$('#game-debug').append('(' + i1 + ',' + j1 + ') ');
				rConn = this._findingConnection(newI, newJ, i2, j2, nextDirI, nextDirJ, xchange);
				if(rConn != false && rConn[rConn.length-1].i == i2 && rConn[rConn.length-1].j == j2){
					for(var i=0;i< rConn.length;i++){
						conn.push(rConn[i]);
					}
					return conn;
				}
			}
		}
		return false;
	},
	_showingConnection : function(points){
		var i, c;
		for(i=0;i< points.length; i++){
			c = this._getCObj(points[i].i, points[i].j);
			c.show().fadeOut(500);
		}
	},
	_checkEndStage : function(){
		return this.gCellsNo == 0;
	},
	_getNotConnectedJCells : function(){
		var ps = [];
		this._jPCells.each(function(){
			if($(this).data('connected') == '0'){
				ps.push($(this));
			}
		});
		return ps;
	},
	_getNotConnectedAndNotBlockedJCells : function(){
		var ps = [];
		this._jPCells.each(function(){
			if($(this).data('connected') == '0' && $(this).data('blocked') == '0'){
				ps.push($(this));
			}
		});
		return ps;
	},
	_checkMovable : function(){
		var ps = this._getNotConnectedAndNotBlockedJCells();
		var psi = null, psj = null, pts = [], i1 , j1, i2, j2, i, j, iVal, jVal;
		for(i=0;i<ps.length-1;i++){
			psi = ps[i];
			i1 = psi.data('i');
			j1 = psi.data('j');
			iVal = psi.data('value');
			for(j = i+1; j< ps.length; j++){
				psj = ps[j];
				jVal = psj.data('value');
				if(iVal != jVal){
					continue;
				}
				// try to find connect from i to j
				i2 = psj.data('i');
				j2 = psj.data('j');
				pts = this._findingConnection(i1, j1, i2, j2, 4, 4, 0)
				if(pts.length > 0){
					return true;
				}
			}
		}
		return false;
	},
	_checkRefreshable : function(){
		return this._refresh > 0;
	},
	_processAfterMove : function(){
		this.gCellsNo -= 2; // reduce 2
		this._score += 10; // add score 
		$('#p_score').text(this._score);
		var endStage = this._checkEndStage();
		var endGame = endStage && this._stage == this._maxStage;
		if(endStage){
			// end game?
			if(endGame){
				this._gameover(true);
			} else {
				this._stageover();
				this._newStage();
			}
		} else {
			// check continue able
			var movable = this._checkMovable();
			if(!movable){
				var refreshable = this._checkRefreshable();
				if(!refreshable){
					this._gameover(false);
				} else {
					this.refresh();
				}
			}
		}
	},
	_gameover : function(win){
		this._stopTimer();
		if(win){
			var response = this._request('youwin');
		} else {
			var response = this._request('youloss');
		}
		alert('Bạn đạt ' + response.score + ' điểm. Điểm của bạn sẽ được ghi vào hệ thống.');
		window.location = this._scoreUrl;
	},
	_stageover : function(){
		this._refresh++; // give you a refresh if pass through the stage
		var resp = this._request('endstage');
		if(resp.scorea >= 0){
			alert('Qua bài! Bạn được thưởng thêm ' + resp.scorea + ' điểm vì hoàn thành trước thời gian');
		} else {
			alert('Qua bài! Bạn bị trừ đi ' + resp.scorea + ' điểm vì quá giờ');
		}
		this._request('newstage');
	},
	_updateGameStatus : function(){
		$('#p_stage').text(this._stage);
		$('#p_refresh').text(this._refresh);
		$('#p_maxstage').text(this._maxStage);
		$('#p_timer').text(this._timer);
		$('#p_score').text(this._score);
	},
	_exchangeCells : function(i1, j1, i2, j2){
		var jObj1 = this._getJObj(i1, j1);
		var jObj2 = this._getJObj(i2, j2);
		var val1 = jObj1.data('value');
		var class1 = 'p_' + val1;
		var conn1 = jObj1.data('connected');
		var val2 = jObj2.data('value');
		var class2 = 'p_' + val2;
		var conn2 = jObj2.data('connected');
		jObj1.data('value', val2).data('connected', conn2).removeClass(class1).addClass(class2);
		jObj2.data('value', val1).data('connected', conn1).removeClass(class2).addClass(class1);
		if(conn1 == '0'){
			jObj2.show();
		} else {
			jObj2.hide();
		}
		if(conn2 == '0'){
			jObj1.show();
		} else {
			jObj1.hide();
		}
	},
	_stageAfterMove : function(){
		this['_stageAfterMove_' + this._stage]();
	},
	_stageAfterMove_1 : function(){
		this._cleanUpBlocked(this._lastMove.i1, this._lastMove.j1);
		this._cleanUpBlocked(this._lastMove.i2, this._lastMove.j2);
	},
	_stageAfterMove_2 : function(){
		// clean top down
		this._cleanUpConnected(this._lastMove.i1, this._lastMove.j1, this._lastMove.i1, 0);
		this._cleanUpConnected(this._lastMove.i2, this._lastMove.j2, this._lastMove.i2, 0);
	},
	_stageAfterMove_3 : function(){
		// clean bottom up
		this._cleanUpConnected(this._lastMove.i1, this._lastMove.j1, this._lastMove.i1, this.gHeight-1);
		this._cleanUpConnected(this._lastMove.i2, this._lastMove.j2, this._lastMove.i2, this.gHeight-1);
	},
	_stageAfterMove_4 : function(){
		// clean left to right
		this._cleanUpConnected(this._lastMove.i1, this._lastMove.j1, 0, this._lastMove.j1);
		this._cleanUpConnected(this._lastMove.i2, this._lastMove.j2, 0, this._lastMove.j2);
	},
	_stageAfterMove_5 : function(){
		// clean right to left
		this._cleanUpConnected(this._lastMove.i1, this._lastMove.j1, this.gWidth -1, this._lastMove.j1);
		this._cleanUpConnected(this._lastMove.i2, this._lastMove.j2, this.gWidth -1, this._lastMove.j2);
	},
	_stageAfterMove_6 : function(){
		// clean center out horizontal side
		var hCenterLeft = Math.floor(this.gWidth / 2) - 1 ;
		if(this._lastMove.i1 <= hCenterLeft){
			// clean center left
			this._cleanUpConnected(this._lastMove.i1, this._lastMove.j1, hCenterLeft, this._lastMove.j1);
		} else {
			this._cleanUpConnected(this._lastMove.i1, this._lastMove.j1, hCenterLeft + 1, this._lastMove.j1);
		}
		if(this._lastMove.i2 <= hCenterLeft){
			// clean center right
			this._cleanUpConnected(this._lastMove.i2, this._lastMove.j2, hCenterLeft, this._lastMove.j2);
		} else {
			this._cleanUpConnected(this._lastMove.i2, this._lastMove.j2, hCenterLeft + 1, this._lastMove.j2);
		}
	},
	_stageAfterMove_7 : function(){
		// clean center in horizontal side
		var hCenterLeft = Math.floor(this.gWidth / 2) - 1 ;
		if(this._lastMove.i1 <= hCenterLeft){
			// clean center left
			this._cleanUpConnected(this._lastMove.i1, this._lastMove.j1, 0, this._lastMove.j1);
		} else {
			this._cleanUpConnected(this._lastMove.i1, this._lastMove.j1, this.gWidth-1, this._lastMove.j1);
		}
		if(this._lastMove.i2 <= hCenterLeft){
			// clean center right
			this._cleanUpConnected(this._lastMove.i2, this._lastMove.j2, 0, this._lastMove.j2);
		} else {
			this._cleanUpConnected(this._lastMove.i2, this._lastMove.j2, this.gWidth-1, this._lastMove.j2);
		}
	},
	_cleanUpBlocked : function(i, j){
		var k, d, i_, j_;
		for(k = 0; k< this._findDirections.length ; k++){
			d = this._findDirections[k];
			i_ = i + d.i;
			j_ = j + d.j;
			if(i_ >= 0 && i_ < this.gWidth && j_ >= 0 && j_ < this.gHeight){
				this._getJObj(i_, j_).data('blocked', '0');
			}
		}
	},
	_cleanUpConnected : function(i1, j1, i2, j2){
		if(i1 != i2 && j1 != j2){
			return; // donothing
		}
		var isH = (i1 == i2);
		var step = 0, k, jObj, kObj, found, lastFound = {i:-1,j:-1}, impacts = {}; 
		if(isH){
			step = j1 < j2 ? 1 : -1;
			while(j1 * step < j2 * step){
				jObj = this._getJObj(i1, j1);
				found = false;
				if(jObj.data('connected') == '1'){
					k = j1 + step;
					while(k * step <= j2 * step){
						kObj = this._getJObj(i1, k);
						if(kObj.data('connected') == '0'){
							found = true;
							lastFound.i = i1; lastFound.j = k;
							impacts[i1+'_'+j1] = {i:i1, j:j1};
							impacts[i1+'_'+k] = {i:i1, j:k};
							this._exchangeCells(i1, j1, i1, k);
							break;
						}
						k += step;
					}
					if(!found){
						break;
					}
				}
				j1 += step;
			}
		} else {
			step = i1 < i2 ? 1 : -1;
			while(i1 * step < i2 * step){
				jObj = this._getJObj(i1, j1);
				found = false;
				if(jObj.data('connected') == '1'){
					k = i1 + step;
					while(k * step <= i2 * step){
						kObj = this._getJObj(k, j1);
						if(kObj.data('connected') == '0'){
							found = true;
							lastFound.i = k; lastFound.j = j1;
							impacts[i1+'_'+j1] = {i:i1, j:j1};
							impacts[k+'_'+j1] = {i:k, j:j1};
							this._exchangeCells(i1, j1, k, j1);
							break;
						}
						k += step;
					}
					if(!found){
						break;
					}
				}
				i1 += step;
			}
		}
		// clean block for last found
		if(lastFound.i != -1 || lastFound.j != -1){
			this._cleanUpBlocked(lastFound.i, lastFound.j);
		} else {
			this._cleanUpBlocked(i1,j1);
		}
		var z, i, j, o, k, d, ni, nj, t, val;
		for(var z in impacts){
			i = impacts[z].i;
			j = impacts[z].j;
			o = this._getJObj(i, j);
			val = o.data('value');
			if(o.data('connected') == 0){
				for(k=0; k< this._findDirections.length; k++){
					d = this._findDirections[k];
					ni = i + d.i;
					nj = j + d.j;
					if(ni >= 0 && nj >=0 && ni < this.gWidth && nj < this.gHeight){
						t = this._getJObj(ni, nj);
						if(t.data('connected') == 0 && t.data('value') == val){
							o.data('blocked', 0);
							t.data('blocked', 0);
						}
					}
				}
			}
		}
	},
	_request : function(action, ret){
		// request the server
		// actions: startgame|endgame|endstage|refresh
		var url = this._url + '/' + action;
		var d = new Date();
		var data = {
			'token' : this._token,
			'moves' : '',
			'timestamp' : d.getTime(),
			'stage' : this._stage,
			'refresh' : this._refresh
		};
		var it = null;
		for(var i = 0; i< this._recentMoves.length; i++){
			it = this._recentMoves[i];
			if(data.moves.length > 0){
				data.moves += ';';
			}
			data.moves += it.i1 + ',' + it.j1 + ',' + it.i2 + ',' + it.j2 + ',' + it.value + ',' + it.timestamp;
		}
		this._recentMoves = []; // clear recent moves after refreshing
		var result = null;
		$.ajax({
			url : url,
			type : 'post',
			data : data,
			dataType : 'json',
			async : false,
			complete : function(){
			},
			success : function(response){
				if(response){
					PIKACHU._token = response.token ? response.token : '';
					PIKACHU._score = response.score ? response.score : PIKACHU._score;
				}
				result = response;
			}
		});
		return result;
	},
	_updateTimer : function(){
		if(this._state == 'playing'){
			this._timer--;
		} else {
			this._timer = this._stageLengthStandard;
		}
		this._updateGameStatus();
	}
};